package com.example.demo52roleauthority.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * authority 描述的的是一个具体的权限，例如针对某一项数据的查询或者删除权限，它是一个 permission，例如 read_employee、delete_employee、update_employee 之类的，这些都是具体的权限。
 *
 * role 则是一个 permission 的集合，它的命名约定就是以 ROLE_ 开始，例如我们定义的 ROLE 是 ROLE_ADMIN、ROLE_USER 等等。我们在 Spring Security 中的很多地方都能看到对 Role 的特殊处理，投票器和决策器中，RoleVoter 在处理 Role 时会自动添加 ROLE_ 前缀。
 *
 * 在项目中，我们可以将用户和角色关联，角色和权限关联，权限和资源关联。
 * 反映到代码上，就是这样：
 * 假设用 Spring Security 提供的 SimpleGrantedAuthority 的代表 authority，然后我们自定义一个 Role。
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 使用 hasAuthority 更具有一致性，你不用考虑要不要加 ROLE_ 前缀，数据库什么样这里就是什么样！
     * 而 hasRole 则不同，代码里如果写的是 admin，框架会自动加上 ROLE_ 前缀，所以数据库就必须是 ROLE_admin
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasRole("user")
                .antMatchers("/admin/**").hasAuthority("admin")
                .antMatchers("/user/**").hasAuthority("user")
                .anyRequest().authenticated()
                .and().formLogin()
                .and().csrf().disable();
    }
}
